/*
 * Copyright (c) 2017,安徽皖通科技股份有限公司 All rights reserved.
 */

package com.wttech.dzzf.process.service.user;

import com.wtkj.exception.BusinessException;
import com.wtkj.vo.dzzf.base.kfwd.CardInfo;
import com.wtkj.vo.dzzf.base.kfwd.FundAccount;
import com.wtkj.vo.dzzf.base.kfwd.OBU;
import com.wtkj.vo.dzzf.base.kfwd.VehicleInfo;
import com.wtkj.vo.dzzf.share.staticvalue.CardStaticValue;
import com.wtkj.vo.dzzf.share.staticvalue.VehicleStaticValue;
import com.wttech.dzzf.check.moduleSet.CheckUserUpload_8;
import com.wttech.dzzf.check.moduleSet.CheckVehicleUpload_9;
import com.wttech.dzzf.process.constant.ExecuteTable;
import com.wttech.dzzf.process.dao.RepeatUserInfoDao;
import com.wttech.dzzf.process.dao.TransferUserInfoDao;
import com.wttech.dzzf.process.model.user.*;
import com.wttech.dzzf.process.service.base.BaseInfoService;
import com.wttech.dzzf.process.util.BusinessUtils;
import com.wttech.dzzf.process.util.CertVerificationService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;

import static com.wtkj.vo.dzzf.share.staticvalue.VehicleStaticValue.VehType.TRUCK_ONE;
import static com.wttech.dzzf.check.moduleSet.CheckVehicleUpload_9.*;
import static com.wttech.dzzf.process.constant.UserConstants.*;

/**
 * 客户详细信息创建业务实现
 *
 * @author MaShibo
 * @date 2017/10/19
 */
@Service
public class UserDetailInfosCreatorService {


	private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailInfosCreatorService.class);


	private static final String CHANNELID_KEY = "CHANNELID";

	@Resource
	private TransferUserInfoDao transferUserInfoDao;

	@Resource
	private RepeatUserInfoDao repeatUserInfoDao;

	@Resource
	private BaseInfoService baseInfoService;

	private Date defaultDate;

	private volatile Map<String, Integer> seqNoMap = new ConcurrentHashMap<>();

	/**
	 * 身份证证件号验证
	 */
	private CertVerificationService.IdCardCheck idCardCheck = new CertVerificationService.IdCardCheck();

	/**
	 * 组织机构代码证验证
	 */
	private CertVerificationService.OrgCertCheck orgCertCheck = new CertVerificationService.OrgCertCheck();


	@PostConstruct
	public void fillOtherInfos() {
		try {
			defaultDate = DateUtils.parseDate(DEFAULT_DATE_STR,
					new String[]{DateFormatUtils.ISO_DATE_FORMAT.getPattern()});
			setDefaultDate(defaultDate);
			setSeqNoMap(repeatUserInfoDao.queryUserSeqNoMap());
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
	}

	/**
	 * 创建客户信息记录
	 *
	 * @param user 客户信息
	 */
	void createUserInfo(User user) {
		try {
			transferUserInfoDao.createTestObjcet(user);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			LOGGER.error("错误的客户信息{}", user);
			throw new BusinessException("客户信息创建失败！");
		}
	}

	synchronized String buildUserId(Date optOn) {
		String ymd = DateFormatUtils.format(optOn, DEFAULT_DATE_PATTERN);
		Integer count = seqNoMap.get(ymd);
		if (count == null) {
			count = 1;
		} else if (count >= 88888) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(optOn);
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			return buildUserId(calendar.getTime());
		}
		StringBuilder seqNo = new StringBuilder(String.valueOf(count));
		while (seqNo.length() < 5) {
			seqNo.insert(0, "0");
		}
		seqNoMap.put(ymd, count + 1);
		return DEFAULT_ISSUER_NO + ymd + seqNo;
	}

	public <T> void getFutureResult(List<Future<T>> futures) {
		baseInfoService.getFutureResult(futures);
	}

	/**
	 * 创建错误证件记录
	 *
	 * @param user        客户信息
	 * @param fundAccount 资金账户信息
	 * @param ecardNo     关联卡号
	 */
	@SuppressWarnings("unused")
	public void createErrorCert(User user, FundAccount fundAccount, String ecardNo) {
		try {
			Integer userIdType = user.getUserIdType();
			boolean errorIdCard = userIdType.equals(101) && !idCardCheck.test(user.getUserIdNum());
			boolean errorOrgCard = userIdType.equals(202) && !orgCertCheck.test(user.getUserIdNum());
			if (userIdType.equals(100) || userIdType.equals(200) || errorIdCard || errorOrgCard) {
				ErrorCert errorCert = new ErrorCert();
				errorCert.setUserId(user.getId());
				errorCert.setTopclass(fundAccount.getTopClass());
				errorCert.setFundAccountId(fundAccount.getFundAccountId());
				errorCert.setEcardNo(ecardNo);
				transferUserInfoDao.createTestObjcet(errorCert);
			}
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			LOGGER.info(user.toString());
		}
	}

	public void dealWithCardAboutInfos(User user, CardInfo cardInfo) {
		String vehPlate = cardInfo.getVehiclePlate();
		Integer vehColor = cardInfo.getVehicleColor();
		String vehicleId = vehPlate + DEFAULT_VEHICLE_CHAR + vehColor;
		if (isDataCreated(vehicleId, ExecuteTable.VEHICLE.getTableName())) {
			LOGGER.info("车辆信息【{}】已经创建", vehicleId);
		}

		// 查询并记录车辆信息
		VehicleInfo vehicleInfo = transferUserInfoDao.queryDzzfVehicleInfo(vehPlate, vehColor);
		if (vehicleInfo == null) {
			LOGGER.debug("卡号{}, 车牌号{}, 车牌颜色{}无对应的车辆信息", new Object[]{cardInfo.getECardNo(), vehPlate, vehColor});
			createVehicleInfoIfNull(user, cardInfo, vehicleId);
		} else {
			//记录车辆信息
			createVehicleInfo(vehicleInfo, user, vehicleId);
		}

		String cardId = cardInfo.getCardNetID() + cardInfo.getECardNo();
		if (isDataCreated(cardId, ExecuteTable.CARD.getTableName())) {
			LOGGER.info("卡片信息【{}】，已经创建", cardId);
			return;
		}

		// 记录用户卡信息
		createCardInfo(cardInfo, user, vehicleId);
	}


	public void dealWithCard(User user, CardInfo cardInfo) {

		String vehPlate = cardInfo.getVehiclePlate();
		Integer vehColor = cardInfo.getVehicleColor();

		//验证车牌信息
		String vehicleId = vehPlate + DEFAULT_VEHICLE_CHAR + vehColor;
		String result = new CheckVehicleUpload_9().checkId(vehicleId);
		String finalVehicleId = baseInfoService.needOutput(result) ?
				DEFAULT_VEHICLE_PLATE + DEFAULT_VEHICLE_CHAR + vehColor : vehicleId;

		//创建车辆信息
		createAllTypeVehicleInfo(user, cardInfo, finalVehicleId);

		// 记录用户卡信息
		createCardInfo(cardInfo, user, finalVehicleId);

		// 记录用户OBU信息
		createObuInfo(cardInfo, user, finalVehicleId);

	}


	private void createAllTypeVehicleInfo(User user, CardInfo cardInfo, String vehicleId) {
		//若已经创建则跳过
		if (transferUserInfoDao.queryVehicleNumByUserId(vehicleId, user.getId()) > 0) {
			return;
		}
		String vehPlate = cardInfo.getVehiclePlate();
		Integer vehColor = cardInfo.getVehicleColor();

		// 查询并记录车辆信息
		VehicleInfo vehicleInfo = transferUserInfoDao.queryDzzfVehicleInfo(vehPlate, vehColor);
		if (vehicleInfo == null) {
			createVehicleInfoIfNull(user, cardInfo, vehicleId);
		} else {
			//记录车辆信息
			createVehicleInfo(vehicleInfo, user, vehicleId);
		}
	}

	/**
	 * 数据是否已被创建
	 *
	 * @param id        数据ID
	 * @param tableName 数据表名
	 * @return 是否已创建
	 */
	private boolean isDataCreated(String id, String tableName) {
		return transferUserInfoDao.queryUserInfoNum(id, tableName) > 0;
	}

	/**
	 * 使用资金账户构建客户信息
	 *
	 * @param fundAccount dzzf资金账户信息
	 * @return 客户信息
	 */
	public User buildUserInfo(FundAccount fundAccount) {
		String fundAccountId = fundAccount.getFundAccountId();
		int ownerType = fundAccount.getOwnerType();
		Integer certifiType = fundAccount.getCertifiType();
		String topClass = fundAccount.getTopClass();

		CheckUserUpload_8 userCheck = new CheckUserUpload_8();

		if (fundAccount.getClientOprDt() == null) {
			fundAccount.setClientOprDt(defaultDate);
		}

		if (ownerType != OLD_OWNERTYPE_USER && ownerType != OLD_OWNERTYPE_COMPANY) {
			LOGGER.info("资金账户【{}】，用户类型【{}】错误", fundAccountId, ownerType);
			ownerType = OLD_OWNERTYPE_USER;
		}

		String id = buildUserId(fundAccount.getClientOprDt());
		String ymd = id.substring(6, 12);
		try {
			fundAccount.setClientOprDt(DateUtils.parseDate(ymd, new String[]{DEFAULT_DATE_PATTERN}));
		} catch (ParseException e2) {
			LOGGER.error(e2.getMessage(), e2);
		}

		User user = new User();
		user.setId(id);

		//用户类型
		user.setUserType(ownerType == OLD_OWNERTYPE_USER ? DEFAULT_USER_USERTYPE : DEFAULT_COMPANY_USERTYPE);
		userCheck.setUserType(user.getUserType());

		//证件类型：符合证件号规则的使用转换后证件号，不符合规则的设置为默认证件类型
		user.setUserIdType(BusinessUtils.convertUserIdType(certifiType, ownerType));
		userCheck.setUserIdType(user.getUserIdType());

		//开户人名称：不允许使用默认值
		String userName = BusinessUtils.regularString(fundAccount.getFundAccountName());
		String result = userCheck.checkUserName(userName);
		if (baseInfoService.needOutput(result)) {
			if ("6107".equals(topClass)) {
				user.setUserName("工行默认");
			} else {
				user.setUserName("默认名称");
			}
		} else {
			user.setUserName(userName);
		}

		//开户人证件号：不允许默认值
		String userIdNum = BusinessUtils.regularString(fundAccount.getCompanyLic());
		user.setUserIdNum(userIdNum);

		//检测证件号
		result = userCheck.checkUserIdNum(userIdNum);
		if (baseInfoService.needOutput(result)) {
			user.setUserIdType(ownerType == OLD_OWNERTYPE_USER ? DEFAULT_USER_USERIDTYPE : DEFAULT_COMPANY_USRERIDTYPE);
			userCheck.setUserIdType(user.getUserIdType());
			result = userCheck.checkUserIdNum(userIdNum);
			if (baseInfoService.needOutput(result)) {
				LOGGER.error("资金账户【{}】，证件号【{}】，证件类型【{}】验证错误【{}】", new Object[]{fundAccountId, userIdNum, user.getUserIdType(), result});
			}
		}

		//开户人或经办人手机号
		String tel = StringUtils.isBlank(fundAccount.getPhone()) ? fundAccount.getMobile() : fundAccount.getPhone();
		result = userCheck.checkTel(tel);
		user.setTel(baseInfoService.needOutput(result) ? DEFAULT_TEL : tel);

		//开户地址
		String address = BusinessUtils.regularString(fundAccount.getAddress());
		result = userCheck.checkAddress(address);
		user.setAddress(baseInfoService.needOutput(result) ? DEFAULT_USER_ADDRESS : address);

		//注册类型默认为线下
		user.setRegisteredType(REGISTEREDTYPE_OFFLINE);


		//渠道编号
		Object channelObj = fundAccount.getExtendProperties().get(CHANNELID_KEY);
		String channelId = channelObj == null ? DEFAULT_CHANNELID : channelObj.toString();
		user.setChannelId(channelId);

		//验证渠道编号
		userCheck.setRegisteredtype(user.getRegisteredType());
		result = userCheck.checkChannelId(user.getChannelId());
		if (baseInfoService.needOutput(result)) {
			LOGGER.error("资金账户【{}】，渠道编号【{}】】验证错误【{}】", new Object[]{fundAccountId, channelId, result});
		}

		user.setRegisteredTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(fundAccount.getClientOprDt()));
		user.setStatus(fundAccount.getAccountStatus() == 1 ? DEFAULT_INUSE_STATUS : DEFAULT_UNUSE_STATUS);
		user.setStatusChangeTime(user.getRegisteredTime());
		user.setOperation(ADD_OPERATION);

		// 单位用户
		if (user.getUserType() == DEFAULT_COMPANY_USERTYPE) {

			//不符合规范的经办人取默认值
			String agentName = StringUtils.isBlank(fundAccount.getRelationName()) ? user.getUserName() : BusinessUtils.regularString(fundAccount.getRelationName());
			result = userCheck.checkAgentName(agentName);
			user.setAgentName(baseInfoService.needOutput(result) ? DEFAULT_AGENTNAME : agentName);

			//经办人证件类型
			user.setAgentIdType(BusinessUtils.convertUserIdType(fundAccount.getAgentIdType(), OLD_OWNERTYPE_USER));
			userCheck.setAgentIdType(user.getAgentIdType());

			//不符合规范的经办人证件号取默认值
			String agentIdNum = fundAccount.getAgentIdNum();
			result = userCheck.checkAgentIdNum(agentIdNum);
			user.setAgentIdNum(baseInfoService.needOutput(result) ? DEFAULT_AGENTIDNUM : agentIdNum);

			//部门默认为：topClass + 账户类型 + 序号
			user.setDepartment(fundAccount.getTopClass() + fundAccount.getAccountType() + "1");
		}
		return user;
	}

	/**
	 * 创建客户卡关联记录
	 *
	 * @param userId   客户ID
	 * @param cardInfo dzzf卡片信息
	 */
	private void createUserCardInfo(String userId, CardInfo cardInfo) {
		UserCard uc = new UserCard();
		uc.setCardInfoId(cardInfo.getCardInfoId());
		uc.setUserId(userId);
		try {
			transferUserInfoDao.createTestObjcet(uc);
		} catch (Exception e2) {
			LOGGER.debug(e2.getMessage(), e2);
			LOGGER.error("错误的卡-客户关联信息{}", uc);
		}
	}

	/**
	 * 创建卡余额记录
	 *
	 * @param userId   客户ID
	 * @param cardInfo dzzf卡片信息
	 * @return 卡余额信息
	 */
	private void createBalanceInfo(String userId, CardInfo cardInfo) {
		Balance balance = new Balance();
		try {
			balance.setUserId(userId);
			balance.setCardId(cardInfo.getCardNetID() + cardInfo.getECardNo());
			BigDecimal cardBalance = transferUserInfoDao.queryCardBalance(cardInfo.getAccountId());
			balance.setFee(cardBalance.multiply(DEFAULT_FEN_VALUE).longValue());
			if (balance.getFee() < 0L) {
				balance.setFee(0L);
			}
			transferUserInfoDao.createTestObjcet(balance);
		} catch (Exception e) {
			LOGGER.debug(e.getMessage(), e);
			LOGGER.error("错误的卡余额信息{}：", balance.toString());
		}
	}

	/**
	 * 若卡片无对应的车辆信息时创建一条
	 *
	 * @param user      客户信息
	 * @param cardInfo  dzzf卡片信息
	 * @param vehicleId 车辆id
	 * @return 车辆信息
	 */
	private Vehicle createVehicleInfoIfNull(User user, CardInfo cardInfo, String vehicleId) {
		Vehicle vehicle = new Vehicle();
		vehicle.setId(vehicleId);
		vehicle.setType(cardInfo.getVehicleType());
		vehicle.setVin(DEFAULT_VEHICLE_VIN);
		vehicle.setUserId(user.getId());
		vehicle.setRegisteredType(REGISTEREDTYPE_OFFLINE);
		vehicle.setChannelId(user.getChannelId());
		vehicle.setRegisteredTime(user.getRegisteredTime());
		vehicle.setContact(DEFAULT_CONTACT);
		vehicle.setOperation(ADD_OPERATION);
		try {
			transferUserInfoDao.createTestObjcet(vehicle);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			LOGGER.error("错误的车辆信息{}", vehicle);
			throw new BusinessException("临时车辆信息创建失败！");
		}
		return vehicle;
	}

	/**
	 * 创建车辆信息记录
	 *
	 * @param vehicleInfo dzzf车辆信息记录
	 * @param user        客户信息
	 * @param vehicleId   车辆id
	 * @return 车辆信息
	 */
	private Vehicle createVehicleInfo(VehicleInfo vehicleInfo, User user, String vehicleId) {
		CheckVehicleUpload_9 check = new CheckVehicleUpload_9();

		Integer type = vehicleInfo.getVehType();
		String ownerName = vehicleInfo.getOwnerName();
		Integer ownerIdType = vehicleInfo.getOwnerIdType();
		String ownerIdNum = vehicleInfo.getOwnerIdNum();
		String ownerTel = vehicleInfo.getOwnerTel();
		String address = vehicleInfo.getAddress();
		String contact = vehicleInfo.getContact();
		String vehicleType = vehicleInfo.getCertifiVehType();
		String vehicleModel = vehicleInfo.getBrand();
		Integer useCharacter = vehicleInfo.getUseCharacter();
		String vin = vehicleInfo.getVehiclelicNO();
		String engineNum = vehicleInfo.getVehicleEngineNO();
		Date registerDate = vehicleInfo.getRegisterDate();
		Date issueDate = vehicleInfo.getIssueDate();
		String fileNum = vehicleInfo.getFileNum();
		Integer approvedCount = vehicleInfo.getSeats();
		Integer totalMass = vehicleInfo.getWeight();
		Integer maintenanceMass = vehicleInfo.getCurbWeight();
		Integer permittedWeight = vehicleInfo.getLoadLimit();
		Integer vehLength = vehicleInfo.getVehLength();
		Integer vehWidth = vehicleInfo.getVehWidth();
		Integer vehHeight = vehicleInfo.getVehHeight();

		Integer permittedTowWeight = vehicleInfo.getPermittedTowWeight();
		String testRecord = vehicleInfo.getTestRecord();
		Integer wheelCount = vehicleInfo.getWheelCnt();
		Integer axleCount = vehicleInfo.getAxisCnt();
		Integer axleDistance = vehicleInfo.getWheelBase();
		String axisType = vehicleInfo.getAxisType();


		check.setRegisteredTypeTemp(REGISTEREDTYPE_OFFLINE);

		String result;

		Vehicle vehicle = new Vehicle();
		vehicle.setId(vehicleId);

		result = check.checkType(type);
		if (baseInfoService.needOutput(result)) {
			vehicle.setType(VehicleStaticValue.VehType.CAR_ONE.getValue());
		} else {
			vehicle.setType(type);
		}

		vehicle.setUserId(user.getId());

		result = checkOwnerName(ownerName);
		if (baseInfoService.needOutput(result)) {
			vehicle.setOwnerName(DEFAULT_OWNERNAME);
		} else {
			vehicle.setOwnerName(ownerName);
		}

		if (ownerIdType != null) {
			ownerIdType = BusinessUtils.convertUserIdType(vehicleInfo.getOwnerIdType(),
					user.getUserType() == DEFAULT_USER_USERTYPE ? OLD_OWNERTYPE_USER : OLD_OWNERTYPE_COMPANY);
			vehicle.setOwnerIdType(ownerIdType);
			check.setOwnerIdType(ownerIdType);
		}

		result = check.checkOwnerIdNum(ownerIdNum);
		if (baseInfoService.needOutput(result)) {
			vehicle.setOwnerIdNum(DEFAULT_OWNERIDNUM);
		} else {
			vehicle.setOwnerIdNum(ownerIdNum);
		}

		result = checkOwnerTel(ownerTel);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setOwnerTel(ownerTel);
		}

		result = checkAddress(address);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setAddress(address);
		}

		result = check.checkContact(contact);
		if (baseInfoService.needOutput(result)) {
			vehicle.setContact(DEFAULT_CONTACT);
		} else {
			vehicle.setContact(contact);
		}

		result = checkVehicleType(vehicleType);
		if (baseInfoService.needOutput(result)) {
			vehicle.setVehicleType(DEFAULT_VEHICLETYPE);
		} else {
			vehicle.setVehicleType(vehicleType);
		}

		result = checkVehicleModel(vehicleModel);
		if (baseInfoService.needOutput(result)) {
			vehicle.setVehicleModel(DEFAULT_VEHICLEMODEL);
		} else {
			vehicle.setVehicleModel(vehicleModel);
		}

		result = checkUseCharacter(useCharacter);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setUseCharacter(useCharacter);
		}

		result = check.checkVIN(vin);
		if (baseInfoService.needOutput(result)) {
			vehicle.setVin(DEFAULT_VEHICLE_VIN);
		} else {
			vehicle.setVin(vin);
		}

		result = checkEngineNum(engineNum);
		if (baseInfoService.needOutput(result)) {
			vehicle.setEngineNum(DEFAULT_ENGINENUM);
		} else {
			vehicle.setEngineNum(engineNum);
		}


		vehicle.setRegisteredType(REGISTEREDTYPE_OFFLINE);
		vehicle.setChannelId(user.getChannelId());
		vehicle.setRegisteredTime(user.getRegisteredTime());
		if (registerDate != null) {
			vehicle.setRegisterDate(DateFormatUtils.ISO_DATE_FORMAT.format(vehicleInfo.getRegisterDate()));
		}
		if (issueDate != null) {
			vehicle.setIssueDate(DateFormatUtils.ISO_DATE_FORMAT.format(vehicleInfo.getIssueDate()));
		}
		result = checkFileNum(fileNum);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setFileNum(fileNum);
		}

		result = checkApprovedCount(approvedCount);
		if (baseInfoService.needOutput(result)) {
			vehicle.setApprovedCount(DEFAULT_APPROVEDCOUNT);
		} else {
			vehicle.setApprovedCount(approvedCount);
		}

		result = checkTotalMass(totalMass);
		if (baseInfoService.needOutput(result)) {
			vehicle.setTotalMass(DEFAULT_TOTALMASS);
		} else {
			vehicle.setTotalMass(totalMass);
		}

		result = checkMaintenanceMass(maintenanceMass);
		if (baseInfoService.needOutput(result)) {
			vehicle.setMaintenanceMass(DEFAULT_MAINTENANCEMASS);
		} else {
			vehicle.setMaintenanceMass(maintenanceMass);
		}

		result = checkPermittedWeight(permittedWeight);
		if (baseInfoService.needOutput(result)) {
			vehicle.setPermittedWeight(type < TRUCK_ONE.getValue() ? DEFAULT_PERMITTEDWEIGHT_CAR : DEFAULT_PERMITTEDWEIGHT_TRUCK);
		} else {
			vehicle.setPermittedWeight(permittedWeight);
		}

		result = checkPermittedTowWeight(permittedTowWeight);
		if (baseInfoService.needOutput(result)) {
			vehicle.setPermittedTowWeight(type < TRUCK_ONE.getValue() ? DEFAULT_PERMITTEDWEIGHT_CAR : DEFAULT_PERMITTEDTOWWEIGHT_TRUCK);
		} else {
			vehicle.setPermittedTowWeight(permittedTowWeight);
		}

		if (vehHeight != null && vehWidth != null && vehLength != null) {
			String outsideDimensions = vehLength + "X" + vehWidth + "X" + vehHeight;
			result = checkOutsideDimensions(outsideDimensions);
			vehicle.setOutsideDimensions(baseInfoService.needOutput(result) ? DEFAULT_OUTSIDEDIMENSIONS : outsideDimensions);
		} else {
			vehicle.setOutsideDimensions(DEFAULT_OUTSIDEDIMENSIONS);
		}

		result = checkTestRecord(testRecord);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setTestRecord(testRecord);
		}

		result = checkWheelCount(wheelCount);
		if (baseInfoService.needOutput(result)) {
			vehicle.setWheelCount(DEFAULT_WHEELCOUNT);
		} else {
			vehicle.setWheelCount(wheelCount);
		}

		result = checkAxleCount(axleCount);
		if (baseInfoService.needOutput(result)) {
			vehicle.setAxleCount(DEFAULT_AXLECOUNT);
		} else {
			vehicle.setAxleCount(axleCount);
		}

		result = checkAxleDistance(axleDistance);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setAxleDistance(axleDistance);
		}

		result = checkAxisType(axisType);
		if (!baseInfoService.needOutput(result)) {
			vehicle.setAxisType(axisType);
		}

		vehicle.setOperation(ADD_OPERATION);
		try {
			transferUserInfoDao.createTestObjcet(vehicle);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			LOGGER.error("错误车辆信息{}", vehicle.toString());
			throw new BusinessException("临时车辆信息创建失败！");
		}
		return vehicle;
	}

	/**
	 * 创建用户卡信息记录
	 *
	 * @param cardInfo  dzzf卡片信息
	 * @param user      客户信息
	 * @param vehicleId 车辆信息id
	 * @return 用户卡信息
	 */
	private Card createCardInfo(CardInfo cardInfo, User user, String vehicleId) {
		String cardId = cardInfo.getCardNetID() + cardInfo.getECardNo();
		if (isDataCreated(cardId, ExecuteTable.CARD.getTableName())) {
			return null;
		}

		String topClass = cardInfo.getTopClass();
		Integer ecardType = cardInfo.getECardType();
		String cardChannelId = null;
		Object cardChannelObj = cardInfo.getExtendProperties().get(CHANNELID_STR);
		if (cardChannelObj != null) {
			cardChannelId = cardChannelObj.toString();
		}
		Integer newCardType = BusinessUtils.determineCardType(cardInfo.getECardType(), cardInfo.getBindAccountType(), cardInfo.getBindCardType());


		Card card = new Card();

		Integer cardType = newCardType == null ? BusinessUtils.determineCardType(topClass, ecardType) : newCardType;
		Integer cardBrand = cardInfo.getCardBrand() == null ? BusinessUtils.determineCardBrand(cardId, ecardType, topClass) : cardInfo.getCardBrand();
		String channelId = StringUtils.isBlank(cardChannelId) ? DEFAULT_CHANNELID : cardChannelId;

		card.setId(cardId);
		card.setCardType(cardType);
		card.setBrand(cardBrand);
		card.setAgencyId(channelId.substring(0, 11));
		card.setUserId(user.getId());
		card.setVehicleId(vehicleId);
		card.setEnableTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(cardInfo.getStartTime()));
		card.setExpireTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(cardInfo.getEndTime()));
		card.setIssuedType(DEFAULT_CARD_ISSUETYPE);
		card.setChannelId(channelId);
		if (cardInfo.getOptOn() == null) {
			try {
				cardInfo.setOptOn(DateUtils.parseDate("2015-08-17",
						new String[]{DateFormatUtils.ISO_DATE_FORMAT.getPattern()}));
			} catch (ParseException e) {
				LOGGER.error(e.getMessage(), e);
				throw new BusinessException("日期格式化错误");
			}
		}
		card.setIssuedTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(cardInfo.getOptOn()));
		Integer ecardStatus = cardInfo.getEcardStatus();
		card.setStatus(ecardStatus == CardStaticValue.EcardStatus.EcardState_ZC ? 1 : 6);
		card.setStatusChangeTime(card.getIssuedTime());
		card.setOperation(ADD_OPERATION);
		try {
			transferUserInfoDao.createTestObjcet(card);
		} catch (Exception e1) {
			LOGGER.error(e1.getMessage(), e1);
			LOGGER.error("错误用户卡信息{}", card);
			throw new BusinessException("临时卡信息创建失败！");
		}
		return card;
	}

	/**
	 * 创建客户OBU信息
	 *
	 * @param cardInfo  dzzf卡片信息
	 * @param user      客户信息
	 * @param vehicleId 车辆信息ID
	 */
	private void createObuInfo(CardInfo cardInfo, User user, String vehicleId) {
		String vehPlate = cardInfo.getVehiclePlate();
		Integer vehColor = cardInfo.getVehicleColor();

		OBU obuinfo = transferUserInfoDao.queryOBUByCardInfoId(cardInfo.getCardInfoId());
		if (obuinfo == null) {
			List<OBU> obuList = transferUserInfoDao.queryOBUbyVeh(vehPlate, vehColor);

			if (!obuList.isEmpty()) {
				obuList.forEach(obu -> buildAndCreateObu(obu, user, vehicleId));
			}
		}
		if (obuinfo != null) {
			buildAndCreateObu(obuinfo, user, vehicleId);
		}
	}

	/**
	 * 构建OBU信息
	 *
	 * @param obuInfo   dzzfOBU信息
	 * @param user      客户信息
	 * @param vehicleId 车辆ID
	 * @return OBU信息
	 */
	public Obu buildAndCreateObu(OBU obuInfo, User user, String vehicleId) {
		String obuId = obuInfo.getObuId();
		if (isDataCreated(obuId, ExecuteTable.OBU.getTableName())) {
			return null;
		}
		String obuNo = obuInfo.getObuNo();
		String obuChannelId = null;
		Object obuChannelObj = obuInfo.getExtendProperties().get(CHANNELID_STR);
		if (obuChannelObj != null) {
			obuChannelId = obuChannelObj.toString();
		}

		Integer brand = null;
		Object brandObj = obuInfo.getExtendProperties().get("BRAND");
		if (brandObj != null) {
			brand = Integer.valueOf(brandObj.toString());
		}
		String model = null;
		Object modelObj = obuInfo.getExtendProperties().get("MODEL");
		if (modelObj != null) {
			model = modelObj.toString();
		}
		String channelId = StringUtils.isBlank(obuChannelId) ? DEFAULT_CHANNELID : obuChannelId;

		Obu obu = new Obu();
		obu.setId(obuInfo.getObuId());
		obu.setBrand(brand == null ? BusinessUtils.determineObuBrand(obuId, obuNo) : brand);
		obu.setModel(StringUtils.isBlank(model) ? BusinessUtils.determineObuModel(obu.getBrand(), obuNo) : model);
		obu.setUserId(user.getId());
		obu.setVehicleId(vehicleId);
		if (obuInfo.getStartTime() == null) {
			obuInfo.setStartTime(obuInfo.getClientOprDt());
		}
		obu.setEnableTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(obuInfo.getStartTime()));
		if (obuInfo.getEndTime() == null) {
			try {
				obuInfo.setEndTime(DateUtils.parseDate("2025-08-15",
						new String[]{DateFormatUtils.ISO_DATE_FORMAT.getPattern()}));
			} catch (ParseException e) {
				LOGGER.error(e.getMessage(), e);
			}
		}
		obu.setExpireTime(DateFormatUtils.ISO_DATE_FORMAT.format(obuInfo.getEndTime()));
		obu.setRegisteredType(REGISTEREDTYPE_OFFLINE);
		obu.setRegisteredChannelId(channelId);
		obu.setRegisteredTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(obuInfo.getClientOprDt()));
		// 默认网点安装
		obu.setInstallType(2);
		obu.setInstallTime(obu.getRegisteredTime());
		obu.setInstallChannelId(channelId);
		//默认正常状态
		obu.setStatus(1);
		obu.setStatusChangeTime(obu.getRegisteredTime());
		obu.setOperation(ADD_OPERATION);
		/*try {
			transferUserInfoDao.createTestObjcet(obu);
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			LOGGER.error("错误OBU信息{}", obu.toString());
			throw new BusinessException("临时OBU信息创建失败！");
		}*/
		return obu;
	}


	public Map<String, Integer> getSeqNoMap() {
		return seqNoMap;
	}

	void setSeqNoMap(Map<String, Integer> seqNoMap) {
		this.seqNoMap = seqNoMap;
	}

	Date getDefaultDate() {
		return defaultDate;
	}

	private void setDefaultDate(Date defaultDate) {
		this.defaultDate = defaultDate;
	}

}
